package com.acme.bankapp.domain.bank;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * Class representing client
 */
public class Client implements Serializable{



    /**
     * Gender Enum
     */
    public static enum Gender{
        MALE("Mr."), FEMALE("Ms.");

        private String namePrefix;

        Gender(String namePrefix){
            this.namePrefix = namePrefix;
        }

        public String getNamePrefix(){
            return namePrefix;
        }
    }


    private Set<Account> accounts = new HashSet<>();

    private String name;

    private Gender gender;


    /**
     * Constructs client
     */
    public Client(){
    }

    /**
     * Constructs client with specified name
     * @param name Name
     */
    public Client(String name){
        this(name,Gender.MALE);
    }

    /**
     * Constructs client with specified name and gender
     * @param name Name
     * @param gender Gender
     */
    public Client(String name, Gender gender){
        this();
        this.name = name;
        this.gender = gender;
    }

    /**
     * Get client name
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * Get client gender
     * @return Client gender
     */
    public Gender getGender() {
        return gender;
    }

    /**
     * Returns user account
     * @return User's account (or null if not present)
     */
    public Collection<Account> getAccounts() {
        return Collections.unmodifiableCollection(accounts);
    }

    /**
     * Sets user account. To assure integrity use com.acme.bankapp.service.bank.BankService.associateClientWithAccount
     * @see com.acme.bankapp.service.bank.BankService
     * @param account User account to set
     */
    public void addAccount(Account account) {
        this.accounts.add(account);
    }

    public void removeAccount(Account account){
        this.accounts.remove(account);
    }

    /**
     * Get client salutation string
     * @return salutation
     */
    public String getClientSalutation(){
        return gender.getNamePrefix() + " " + name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Client client = (Client) o;

        if (gender != client.gender) return false;
        if (name != null ? !name.equals(client.name) : client.name != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (gender != null ? gender.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder
            .append(" Name: ")
            .append(name)
            .append(" | Gender: ")
            .append(gender.toString());
        return builder.toString();
    }
}
